package inventario.code;

/**
 * Projeto Laboratorio de Programacao II
 * 
 * Classe Sala
 * 
 * Implementa uma sala com objetos de usuario e maquina. Todas as salas
 * tem um numero limite de pessoas e podem ou nao estar ativas.
 * 
 * 
 * @authors Pedro Augusto, Rafael Ribeiro, Talita Lobo
 * 
 */

import java.util.*;

public class Sala {

	private String nome;
	public List<Usuario> usuarios;
	public List<Maquina> maquinas;
	private boolean ativa;
	public int capacidade;

	/**
	 * Construtor da classe Sala, entra-se com nome e capacidade da mesma.
	 * 
	 * @param nome
	 *            Nome da Sala
	 * 
	 * @param capacidade
	 *            Capacidade da Sala
	 * 
	 * @throws Exception
	 *             Lanca excecao no caso do nome da sala ser invalido ou se a
	 *             capacidade da sala for inferior a zero
	 */
	public Sala(String nome, int capacidade) throws Exception {

		if (nome == null || nome.replaceAll(" ", "").equals("")) {
			throw new Exception("O Nome da Sala deve ser Valido.");
		}
		if (capacidade <= 0) {
			throw new Exception("A capacidade da Sala deve ser Maior que Zero.");
		}

		this.nome = nome;

		// chamar metodo para adicionar o nome da sala em um txt.
		// metodo pertencente a uma classe no package DAO.
		this.capacidade = capacidade;
		usuarios = new ArrayList<Usuario>();
		maquinas = new ArrayList<Maquina>();
		this.ativa = true;

	}

	/**
	 * Metodo que retorna o nome da sala.
	 * 
	 * @return O nome da Sala
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * Matodo que muda o nome da sala.
	 * 
	 * @param novoNome
	 *            Novo nome da Sala
	 */
	public void setNome(String novoNome) {
		nome = novoNome;
	}

	/**
	 * Metodo que retorna a capacidade da sala.
	 * 
	 * @return A capacidade da Sala
	 */
	public int getCapacidade() {
		return capacidade;
	}

	/**
	 * Metodo que retorna o numero que usuarios que ainda podem ser adicionados
	 * na sala.
	 * 
	 * @return O numero de usuarios que podem ser adicionados a sala
	 */
	private int getCapacidadeDeUsuariosRestante() {
		return capacidade - usuarios.size();
	}

	/**
	 * 
	 * 
	 * @return A quantidade de maquinas que podem ser adicionadas a sala
	 */
	private int getCapacidadeDeMaquinasRestante() {
		return capacidade - maquinas.size();
	}

	/**
	 * Metodo que retorna a quantidade de pessoas na sala.
	 * 
	 * @return O numero efetivo de ocupantes
	 */
	public int getQuantUsuarios() {
		return usuarios.size();
	}

	/**
	 * Metodo que retorna a quantidade de alocadas.
	 * 
	 * @return : A quantidade de Maquinas Usadas
	 */
	public int getQuantMaquinas() {
		return maquinas.size();
	}

	/**
	 * Metodo que retorna um booleano mostrando se a sala esta ativada ou
	 * desativada.
	 * 
	 * @param estado
	 *            O novo status da sala
	 */
	public boolean getAtiva() {
		return ativa;
	}

	/**
	 * Metodo que muda o status da sala, se ela esta ativada ou desativada.
	 * 
	 * @return : O numero de vagas disponiveis da sala
	 */
	public void setAtiva(boolean estado) {
		this.ativa = estado;
	}

	/**
	 * Metodo que retorna um valor inteiro mostrando um valor positivo com o
	 * indice do objeto no caso dele existir na lista, e -1 no caso de nao
	 * existir o objeto na lista.
	 * 
	 * @param usuario
	 *            Usuario a ser pesquisado
	 * @return O indice do usuario procurado, caso seja encontrado e um numero
	 *         negativo caso nao seja encontrada
	 */
	public int contemUsuario(Usuario usuario) {
		return usuarios.indexOf(usuario);
	}

	/**
	 * Metodo que verifica se a sala esta cheia antes de adiciona-lo a sala,
	 * retornando true caso adicione e false caso nao adicione.
	 * 
	 * @param user
	 *            Usuario a ser adicionado
	 * 
	 * @return True se adicionado com sucesso, false se nao adicionado
	 * 
	 * @throws Exception
	 */
	public boolean adicionaUsuario(Usuario user) throws Exception {

		if (getCapacidadeDeUsuariosRestante() == 0) {
			throw new Exception("A Sala Esta cheia! ");
		} else {

			if (user != null) {
				usuarios.add(user);

				return true;
			}

		}
		return false;
	}

	/**
	 * Metodo que remove usuarios da sala, retorna true para existente e
	 * removido e false para nao existente/ nao removido.
	 * 
	 * @param user
	 *            O usuario a ser removido
	 * 
	 * @return True se removido com sucesso e false caso mal sucedido
	 */
	public boolean removeUsuario(Usuario user) {
		if (contemUsuario(user) >= 0) {
			usuarios.remove(user);
			return true;
		}
		return false;
	}

	/**
	 * Metodo que retorna um inteiro positivo com o indice da maquina caso ela
	 * exista na lista, caso ela nao exista, retorna -1
	 * 
	 * @param maquina
	 *            Maquina a ser pesquisada
	 * @return : O indice da maquina procurada, caso seja encontrada e um numero
	 *         negativo caso nao seja encontrada
	 */
	public int contemMaquina(Maquina maquina) {
		return maquinas.indexOf(maquina);
	}

	/**
	 * Metodo que adiciona maquina a sala caso haja capacidade.
	 * 
	 * @param maq
	 *            Maquina a ser adicionada
	 * 
	 * @return True se adicionada com sucesso, false caso nao seja adicionada
	 * 
	 * @throws Exception
	 */
	public boolean adicionaMaquina(Maquina maq) throws Exception {

		if (getCapacidadeDeMaquinasRestante() == 0) {
			throw new Exception("A Sala Esta Cheia.");

		}
		if (maq != null) {
			maquinas.add(maq);
			return true;
		}
		return false;
	}

	/**
	 * Metodo que remove uma maquina da sala, caso a maquina exista.
	 * 
	 * @param maq
	 *            Maquina a ser removida
	 * @return True se removida com sucesso, false se mal sucedida a operacao
	 */

	public boolean removeMaquina(Maquina maq) {

		if (contemMaquina(maq) >= 0) {
			maquinas.remove(maq);
			return true;
		}
		return false;
	}

	/**
	 * Metodo que compara dois objetos do tipo sala e responde com um booleano
	 * se eles sao iguais.
	 * 
	 * @param sala
	 *            Adiciona um objeto do tipo Sala para comparar com outro objeto
	 *            do tipo Sala.
	 * 
	 * @return Retorna um booleano indicando se os objetos sao iguais.
	 */
	public boolean equals(Object sala) {
		if (!(sala instanceof Sala)) {
			return false;
		}
		Sala salaEquals = (Sala) sala;
		return (getNome().equals(salaEquals.getNome()))
				&& (getQuantUsuarios() == salaEquals.getQuantUsuarios())
				&& (getQuantMaquinas() == salaEquals.getQuantMaquinas())
				&& (getCapacidade() == salaEquals.getCapacidade());
	}

	/**
	 * Metodo que retorna as informacoes sobre a sala.
	 */
	public String toString() {
		String usuario = "";
		for (Usuario user : usuarios) {
			if (user != null) {
				usuario += user.getNome() + "\n";
			}
		}
		return ".: Sala - " + getNome() + "\n.: Capacidade - "
				+ getCapacidade() + "\n.: Quantidade de Alocadores - "
				+ getQuantUsuarios() + "\n.: Numero de Maquinas - "
				+ getQuantMaquinas() + "\n.: Usuarios - " + usuario;
	}

}
